/*! \file
 * \brief Enter a brief description here.
 *
 * Enter a detailed description here. (optional)
 * \author Author (Ivo Wingelaar)
 * \date Date (2011)
 * \version Version (0.0.1)
 * \copyright Copyright (GNU LGPL v3)
 */

#ifndef __LYNX_CURSOR_MANAGER_LINUX_C_HPP_INCLUDED__
#define __LYNX_CURSOR_MANAGER_LINUX_C_HPP_INCLUDED__

#include "LynxCursorManager.hpp"

#ifdef _LYNX_LINUX_

#include <X11/Xlib.h>

namespace Lynx
{

/** class                **/
/** CursorManagerLinux_C **/
//! A linux implementation of the CursorManager.
class CursorManagerLinux_C : public CursorManager
{
public:
    /** constructor **/
    /// \param    WindowManagerLinux_C* window
    ///         A pointer to a linux windowmanager.
    CursorManagerLinux_C(Display** display_ptr, Window* window_ptr, uint32_t* width_ptr, uint32_t* height_ptr);

    /** default destructor **/
    virtual ~CursorManagerLinux_C();

    /** virtual function **/
    /** set_visible      **/
    //! Sets if the cursor should be visible.
    /// \return void
    /// \param    bool visible
    ///         True if you want the cursor to be visible, false otherwise.
    virtual void set_visible(bool visible);

    /** const virtual function **/
    /** is_visible             **/
    //! Returns if the cursor is visible.
    /// \return bool
    ///         True if the cursor is visible, false otherwise.
    /// \param  void
    virtual bool is_visible(void) const;

    /** virtual function **/
    /** set_position     **/
    //! Sets the position of the cursor.
    /// \return void
    /// \param    const Core::Vector2f& pos
    ///         The relative position of the cursor on the screen.
    virtual void set_position(const Myth::Math::Vector2f& pos);

    /** virtual function **/
    /** set_position     **/
    //! Sets the position of the cursor.
    /// \return void
    /// \param    float x
    ///         The relative x-coord of the cursor.
    /// \param    float y
    ///         The relative y-coord of the cursor.
    virtual void set_position(float x,
                              float y);

    /** virtual function **/
    /** set_position     **/
    //! Sets the position of the cursor.
    /// \return void
    /// \param    const Core::Vector2i& pos
    ///         The absolute position of the cursor on the screen.
    virtual void set_position(const Myth::Math::Vector2i& pos);

    /** virtual function **/
    /** set_position     **/
    //! Sets the position of the cursor.
    /// \return void
    /// \param    int32_t x
    ///         The absolute x-coord of the cursor.
    /// \param    int32_t y
    ///         The absolute y-coord of the cursor.
    virtual void set_position(int32_t x,
                              int32_t y);

    /** const virtual function **/
    /** get_position           **/
    //! Returns the absolute position of the cursor.
    /// \return Core::Vector2i
    ///         The absolute position of the cursor.
    /// \param  void
    virtual Myth::Math::Vector2i get_position(void);

    /** const virtual function **/
    /** get_relative_position  **/
    //! Returns the relative position of the cursor.
    /// \return Core::Vector2f
    ///         The relative position of the cursor.
    /// \param  void
    virtual Myth::Math::Vector2f get_relative_position(void);

    /** virtual function   **/
    /** set_reference_rect **/
    //! Sets a new reference rectangle for the cursor positions.
    /// \return void
    /// \param    Core::Rectanglei* rect
    ///         A pointer to the new reference rectangle for the relative and absolute positions.
    virtual void set_reference_rect(Myth::Math::Rectanglei* rect = 0);

private:
    /** function          **/
    /** update_cursor_pos **/
    //! Updates the position of the cursor.
    /// \return void
    /// \param  void
    void update_cursor_pos(void);

    //
    Display** mDisplay;
    Window* mWindow;
    uint32_t* mWidth;
    uint32_t* mHeight;
    //

    //! The position of the cursor.
    Myth::Math::Vector2i mCursorPos;
    //! The reference rectangle.
    Myth::Math::Rectanglei mReferenceRect;
    //! The invisible cursor object.
    Cursor mInvisCursor;
    //! Is the cursor visible?
    bool mIsVisible;
    //! Should we use the reference rectangle?
    bool mUseReferenceRect;
};

} // namespace Lynx

#endif // _LYNX_LINUX_

#endif // __LYNX_CURSOR_MANAGER_LINUX_C_HPP_INCLUDED__

